home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oh!X 2001 Spring
/
Oh!X 2001 Spring Special CD-ROM (Japan).7z
/
Oh!X 2001 Spring Special CD-ROM (Japan) (Track 1).bin
/
TCLTK
/
OCTREV
/
octrev.tcl
< prev
next >
Wrap
Text File
|
2000-05-07
|
8KB
|
333 lines
#
# octrev.tcl : 8角リバーシ
#
# Copyright (C) 2000 by Makoto Hiroi
#
# 大域変数
# piece() : 駒を表す図形 id を格納
# action : 0 : 先手, 1 : 後手
# color : 駒の色
# play_flag : ゲーム進行用フラグ 1 :先手(黒), 2 : 後手(白)
# level : 思考レベル
# message : メッセージ表示用ラベル
# score : 玉数表示用ラベル
# last_score: 最終スコア予想
# black_piece : 黒の残り(DLL 側でセット)
# white_piece : 白の残り(DLL 側でセット)
# VALUE : 評価値(DLL 側でセット)
#
# octrev.dll で追加されるコマンド
#
# init_game : ゲームの初期化
# think $level $turn $random : 思考ルーチン
# reverse $n $turn : ひっくり返る位置をリストで返す
# check_reverse $n $turn : 駒を裏返すことができるか
# count_place $turn : 駒を置ける場所の数
#
# 思考ルーチンロード
load octrev.dll
# ヘルプファイルの表示
proc help {} {
global argv0
if {![winfo exist .t0]} {
toplevel .t0
wm title .t0 "Oct Reversi Help"
text .t0.text -yscrollcommand ".t0.scroll set"
scrollbar .t0.scroll -command ".t0.text yview"
pack .t0.scroll -side right -fill y
pack .t0.text -side left
# 起動パスを取得
set path [file dirname $argv0]
# ファイルの読み込み
set f [open "$path/octrev.txt" r]
while {![eof $f]} {
.t0.text insert end [read $f 1000]
}
close $f
.t0.text configure -state disabled
}
}
# 駒を描画する
proc draw_piece {n c} {
global piece color
.c0 itemconfigure $piece($n) -fill $color($c)
.c0 raise $piece($n)
}
# 駒を置く
proc put_piece {piece_list turn} {
foreach n $piece_list {
draw_piece $n $turn
update
after 250
}
display_score
}
# メッセージの表示
proc display_message {m} {
global message mes_table
set message $mes_table($m)
update
after 500
}
# スコアの表示
proc display_score {} {
global score white_piece black_piece
set score [format "黒 %2d 石 : 白 %2d 石" $black_piece $white_piece]
update
}
# 予想スコアの表示
proc display_last_score {} {
global last_score VALUE
set result [expr abs($VALUE)]
if {$VALUE > 0 } {
.ll configure -fg black
set m [format "黒の %2d 石勝ちでしょう" $result]
} elseif {$VALUE < 0} {
.ll configure -fg white
set m [format "白の %2d 石勝ちでしょう" $result]
} else {
set m "引き分けでしょう"
}
set last_score $m
update
}
# 終了ダイアログ
proc game_over {} {
global play_flag action white_piece black_piece
set c [expr $black_piece - $white_piece]
if {$c == 0} {
set m "引き分けです"
} elseif {($action == 0 && $c > 0) || ($action == 1 && $c < 0)} {
set m "あなたの勝ちです"
} else {
set m "私の勝ちです"
}
tk_messageBox -type ok -message $m
set play_flag 0
display_message start
}
# 探索レベルの決定
proc decide_level {level} {
global white_piece black_piece
set rest [expr 60 - $white_piece - $black_piece]
# レベル5で残り 14 手で読み切り
if {[expr 9 + $level] >= $rest} {
# 読み切りモード
display_message finish
return 20
}
return $level
}
# コンピュータ側の手番
proc put_piece_com {} {
global play_flag level action white_piece black_piece random
# コマンド think で使う大域変数
global VALUE
while {1} {
. configure -cursor wait
display_message com_turn
set turn [expr $play_flag - 1]
set lv [decide_level $level]
set result [think $lv $turn $random]
. configure -cursor ""
if {$lv == 20} {
display_last_score
}
put_piece $result $turn
# 状態チェック
if {[count_place $action] == 0} {
if {[count_place $turn] == 0} {
game_over
return
} else {
# 相手がパスだよ
display_message pass
}
} else {
break;
}
}
# 手番を移す
if {$play_flag == 1} {
set play_flag 2
} else {
set play_flag 1
}
display_message my_turn
}
# 人間側の指し手
proc put_piece_human {n} {
global play_flag white_piece black_piece action message
# 自分の手番かチェックする
if {$play_flag != [expr $action + 1]} return
# 駒を反転できるかチェックする
if ![check_reverse $n $action] return
# 二重入力防止
set $play_flag -1
# 駒の位置がリストで返される
put_piece [reverse $n $action] $action
# 状態チェック
if {[count_place [expr !$action]] == 0} {
if {[count_place $action] == 0} {
# 両方とも打つ場所無し
game_over
return
} else {
# 相手はパスだよ
display_message pass
display_message my_turn
return
}
}
# 元に戻す
set play_falg [expr $action + 1]
# 手番を移す
if {$play_flag == 1} {
set play_flag 2
} else {
set play_flag 1
}
display_message com_turn
put_piece_com
}
# 中断ダイアログ
proc break_dialog {} {
set ans [tk_messageBox -type yesno -icon question \
-message "今のゲームを中断しますか?"]
return [expr {($ans == "no") ? 0 : 1}]
}
# 駒を隠す
proc hide_piece {} {
global piece
for {set i 0} {$i < 64} {incr i} {
.c0 lower $piece($i)
}
}
# ゲームの開始
proc new_game {} {
global play_flag action white_piece black_piece last_score
if {$play_flag != 0} {
if ![break_dialog] return
set play_flag 0
}
hide_piece
if {$play_flag == 0 } {
# ゲーム開始
init_game
set white_piece 2
set black_piece 2
# 最初の駒を描画
draw_piece 27 1
draw_piece 28 0
draw_piece 35 0
draw_piece 36 1
set play_flag 1
set last_score ""
display_score
if $action {
put_piece_com
} else {
display_message my_turn
}
}
}
# グローバル変数の初期化
proc init_global {} {
global level action mes_table play_flag message color random
set level 1
set random 1
set action 0
set play_flag 0
set color(0) black
set color(1) white
set mes_table(start) "メニュー Games の Start でゲーム開始!"
set mes_table(my_turn) "あなたの手番です"
set mes_table(com_turn) "わたしの手番です"
set mes_table(pass) "・・・パスです・・・"
set mes_table(finish) "最後まで読み切ります!"
set message $mes_table(start)
}
# ********** メニューの設定 **********
menu .m -type menubar
. configure -menu .m
.m add cascade -label "Games" -under 0 -menu .m.m1
.m add cascade -label "Level" -under 0 -menu .m.m2
.m add command -label "Help" -under 0 -command "help"
menu .m.m1 -tearoff no
.m.m1 add command -label "Start" -under 0 -command "new_game"
.m.m1 add separator
.m.m1 add radiobutton -label "先手" -variable action -value 0
.m.m1 add radiobutton -label "後手" -variable action -value 1
.m.m1 add separator
.m.m1 add checkbutton -label "Rand" -variable random
.m.m1 add separator
.m.m1 add command -label "Exit" -under 0 -command "exit"
menu .m.m2 -tearoff no
.m.m2 add radiobutton -label "Level 0" -variable level -value 0
.m.m2 add radiobutton -label "Level 1" -variable level -value 1
.m.m2 add radiobutton -label "Level 2" -variable level -value 2
.m.m2 add radiobutton -label "Level 3" -variable level -value 3
.m.m2 add radiobutton -label "Level 4" -variable level -value 4
.m.m2 add radiobutton -label "Level 5" -variable level -value 5
# ********** 画面の生成 **********
option add *font "{MS 明朝} 12"
canvas .c0 -width 340 -height 340 -bg green4
# 図形の初期化 マスのサイズは 40 * 40
for {set n 0; set y 0} {$y < 8} {incr y} {
for {set x 0} {$x < 8} {incr x} {
set x1 [expr $x * 40 + 10]
set y1 [expr $y * 40 + 10]
set x2 [expr $x1 + 40]
set y2 [expr $y1 + 40]
if { !(($n == 0) || ($n == 7) ||($n == 56) || ($n == 63)) } {
set i [.c0 create rectangle $x1 $y1 $x2 $y2 -fill green4]
.c0 bind $i <Button-1> "put_piece_human $n"
}
# 石の描画
incr x1 4
incr y1 4
incr x2 -4
incr y2 -4
set piece($n) [.c0 create oval $x1 $y1 $x2 $y2 -outline green4]
.c0 lower $piece($n)
incr n 1
}
}
# メッセージ表示用ラベル
label .lm -textvariable message -bg green4 -fg yellow
# スコア表示用
label .ls -textvariable score -bg green4 -fg white
# 予想スコア
label .ll -textvariable last_score -bg green4 -fg black
pack .ls .lm .ll .c0 -fill x
init_global
wm title . "Reversi"
wm resizable . 0 0
focus -force .
# end of file